home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / email / feedparser.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-10-13  |  9.0 KB  |  416 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __all__ = [
  5.     'FeedParser']
  6. import re
  7. from email import errors
  8. from email import message
  9. NLCRE = re.compile('\r\n|\r|\n')
  10. NLCRE_bol = re.compile('(\r\n|\r|\n)')
  11. NLCRE_eol = re.compile('(\r\n|\r|\n)$')
  12. NLCRE_crack = re.compile('(\r\n|\r|\n)')
  13. headerRE = re.compile('^(From |[\\041-\\071\\073-\\176]{1,}:|[\\t ])')
  14. EMPTYSTRING = ''
  15. NL = '\n'
  16. NeedMoreData = object()
  17.  
  18. class BufferedSubFile(object):
  19.     
  20.     def __init__(self):
  21.         self._partial = ''
  22.         self._lines = []
  23.         self._eofstack = []
  24.         self._closed = False
  25.  
  26.     
  27.     def push_eof_matcher(self, pred):
  28.         self._eofstack.append(pred)
  29.  
  30.     
  31.     def pop_eof_matcher(self):
  32.         return self._eofstack.pop()
  33.  
  34.     
  35.     def close(self):
  36.         self._lines.append(self._partial)
  37.         self._partial = ''
  38.         self._closed = True
  39.  
  40.     
  41.     def readline(self):
  42.         if not self._lines:
  43.             if self._closed:
  44.                 return ''
  45.             
  46.             return NeedMoreData
  47.         
  48.         line = self._lines.pop()
  49.         for ateof in self._eofstack[::-1]:
  50.             if ateof(line):
  51.                 self._lines.append(line)
  52.                 return ''
  53.                 continue
  54.         
  55.         return line
  56.  
  57.     
  58.     def unreadline(self, line):
  59.         self._lines.append(line)
  60.  
  61.     
  62.     def push(self, data):
  63.         data = self._partial + data
  64.         self._partial = ''
  65.         parts = NLCRE_crack.split(data)
  66.         self._partial = parts.pop()
  67.         lines = []
  68.         for i in range(len(parts) // 2):
  69.             lines.append(parts[i * 2] + parts[i * 2 + 1])
  70.         
  71.         self.pushlines(lines)
  72.  
  73.     
  74.     def pushlines(self, lines):
  75.         self._lines[:0] = lines[::-1]
  76.  
  77.     
  78.     def is_closed(self):
  79.         return self._closed
  80.  
  81.     
  82.     def __iter__(self):
  83.         return self
  84.  
  85.     
  86.     def next(self):
  87.         line = self.readline()
  88.         if line == '':
  89.             raise StopIteration
  90.         
  91.         return line
  92.  
  93.  
  94.  
  95. class FeedParser:
  96.     
  97.     def __init__(self, _factory = message.Message):
  98.         self._factory = _factory
  99.         self._input = BufferedSubFile()
  100.         self._msgstack = []
  101.         self._parse = self._parsegen().next
  102.         self._cur = None
  103.         self._last = None
  104.         self._headersonly = False
  105.  
  106.     
  107.     def _set_headersonly(self):
  108.         self._headersonly = True
  109.  
  110.     
  111.     def feed(self, data):
  112.         self._input.push(data)
  113.         self._call_parse()
  114.  
  115.     
  116.     def _call_parse(self):
  117.         
  118.         try:
  119.             self._parse()
  120.         except StopIteration:
  121.             pass
  122.  
  123.  
  124.     
  125.     def close(self):
  126.         self._input.close()
  127.         self._call_parse()
  128.         root = self._pop_message()
  129.         if root.get_content_maintype() == 'multipart' and not root.is_multipart():
  130.             root.defects.append(errors.MultipartInvariantViolationDefect())
  131.         
  132.         return root
  133.  
  134.     
  135.     def _new_message(self):
  136.         msg = self._factory()
  137.         if self._cur and self._cur.get_content_type() == 'multipart/digest':
  138.             msg.set_default_type('message/rfc822')
  139.         
  140.         if self._msgstack:
  141.             self._msgstack[-1].attach(msg)
  142.         
  143.         self._msgstack.append(msg)
  144.         self._cur = msg
  145.         self._last = msg
  146.  
  147.     
  148.     def _pop_message(self):
  149.         retval = self._msgstack.pop()
  150.         if self._msgstack:
  151.             self._cur = self._msgstack[-1]
  152.         else:
  153.             self._cur = None
  154.         return retval
  155.  
  156.     
  157.     def _parsegen(self):
  158.         self._new_message()
  159.         headers = []
  160.         for line in self._input:
  161.             if line is NeedMoreData:
  162.                 yield NeedMoreData
  163.                 continue
  164.             
  165.             if not headerRE.match(line):
  166.                 if not NLCRE.match(line):
  167.                     self._input.unreadline(line)
  168.                 
  169.                 break
  170.             
  171.             headers.append(line)
  172.         
  173.         self._parse_headers(headers)
  174.         if self._headersonly:
  175.             lines = []
  176.             while True:
  177.                 line = self._input.readline()
  178.                 if line is NeedMoreData:
  179.                     yield NeedMoreData
  180.                     continue
  181.                 
  182.                 if line == '':
  183.                     break
  184.                 
  185.                 lines.append(line)
  186.             self._cur.set_payload(EMPTYSTRING.join(lines))
  187.             return None
  188.         
  189.         if self._cur.get_content_type() == 'message/delivery-status':
  190.             while True:
  191.                 self._input.push_eof_matcher(NLCRE.match)
  192.                 for retval in self._parsegen():
  193.                     if retval is NeedMoreData:
  194.                         yield NeedMoreData
  195.                         continue
  196.                     
  197.                 
  198.                 msg = self._pop_message()
  199.                 self._input.pop_eof_matcher()
  200.                 while True:
  201.                     line = self._input.readline()
  202.                     if line is NeedMoreData:
  203.                         yield NeedMoreData
  204.                         continue
  205.                     
  206.                     break
  207.                 while True:
  208.                     line = self._input.readline()
  209.                     if line is NeedMoreData:
  210.                         yield NeedMoreData
  211.                         continue
  212.                     
  213.                     break
  214.                 if line == '':
  215.                     break
  216.                 
  217.                 self._input.unreadline(line)
  218.             return None
  219.         
  220.         if self._cur.get_content_maintype() == 'message':
  221.             for retval in self._parsegen():
  222.                 if retval is NeedMoreData:
  223.                     yield NeedMoreData
  224.                     continue
  225.                 
  226.             
  227.             self._pop_message()
  228.             return None
  229.         
  230.         if self._cur.get_content_maintype() == 'multipart':
  231.             boundary = self._cur.get_boundary()
  232.             if boundary is None:
  233.                 self._cur.defects.append(errors.NoBoundaryInMultipartDefect())
  234.                 lines = []
  235.                 for line in self._input:
  236.                     if line is NeedMoreData:
  237.                         yield NeedMoreData
  238.                         continue
  239.                     
  240.                     lines.append(line)
  241.                 
  242.                 self._cur.set_payload(EMPTYSTRING.join(lines))
  243.                 return None
  244.             
  245.             separator = '--' + boundary
  246.             boundaryre = re.compile('(?P<sep>' + re.escape(separator) + ')(?P<end>--)?(?P<ws>[ \\t]*)(?P<linesep>\\r\\n|\\r|\\n)?$')
  247.             capturing_preamble = True
  248.             preamble = []
  249.             linesep = False
  250.             while True:
  251.                 line = self._input.readline()
  252.                 if line is NeedMoreData:
  253.                     yield NeedMoreData
  254.                     continue
  255.                 
  256.                 if line == '':
  257.                     break
  258.                 
  259.                 mo = boundaryre.match(line)
  260.                 if mo:
  261.                     if mo.group('end'):
  262.                         linesep = mo.group('linesep')
  263.                         break
  264.                     
  265.                     if capturing_preamble:
  266.                         if preamble:
  267.                             lastline = preamble[-1]
  268.                             eolmo = NLCRE_eol.search(lastline)
  269.                             if eolmo:
  270.                                 preamble[-1] = lastline[:-len(eolmo.group(0))]
  271.                             
  272.                             self._cur.preamble = EMPTYSTRING.join(preamble)
  273.                         
  274.                         capturing_preamble = False
  275.                         self._input.unreadline(line)
  276.                         continue
  277.                     
  278.                     while True:
  279.                         line = self._input.readline()
  280.                         if line is NeedMoreData:
  281.                             yield NeedMoreData
  282.                             continue
  283.                         
  284.                         mo = boundaryre.match(line)
  285.                         if not mo:
  286.                             self._input.unreadline(line)
  287.                             break
  288.                             continue
  289.                     self._input.push_eof_matcher(boundaryre.match)
  290.                     for retval in self._parsegen():
  291.                         if retval is NeedMoreData:
  292.                             yield NeedMoreData
  293.                             continue
  294.                         
  295.                     
  296.                     if self._last.get_content_maintype() == 'multipart':
  297.                         epilogue = self._last.epilogue
  298.                         if epilogue == '':
  299.                             self._last.epilogue = None
  300.                         elif epilogue is not None:
  301.                             mo = NLCRE_eol.search(epilogue)
  302.                             if mo:
  303.                                 end = len(mo.group(0))
  304.                                 self._last.epilogue = epilogue[:-end]
  305.                             
  306.                         
  307.                     else:
  308.                         payload = self._last.get_payload()
  309.                         if isinstance(payload, basestring):
  310.                             mo = NLCRE_eol.search(payload)
  311.                             if mo:
  312.                                 payload = payload[:-len(mo.group(0))]
  313.                                 self._last.set_payload(payload)
  314.                             
  315.                         
  316.                     self._input.pop_eof_matcher()
  317.                     self._pop_message()
  318.                     self._last = self._cur
  319.                     continue
  320.                 preamble.append(line)
  321.             if capturing_preamble:
  322.                 self._cur.defects.append(errors.StartBoundaryNotFoundDefect())
  323.                 self._cur.set_payload(EMPTYSTRING.join(preamble))
  324.                 epilogue = []
  325.                 for line in self._input:
  326.                     if line is NeedMoreData:
  327.                         yield NeedMoreData
  328.                         continue
  329.                         continue
  330.                 
  331.                 self._cur.epilogue = EMPTYSTRING.join(epilogue)
  332.                 return None
  333.             
  334.             if linesep:
  335.                 epilogue = [
  336.                     '']
  337.             else:
  338.                 epilogue = []
  339.             for line in self._input:
  340.                 if line is NeedMoreData:
  341.                     yield NeedMoreData
  342.                     continue
  343.                 
  344.                 epilogue.append(line)
  345.             
  346.             if epilogue:
  347.                 firstline = epilogue[0]
  348.                 bolmo = NLCRE_bol.match(firstline)
  349.                 if bolmo:
  350.                     epilogue[0] = firstline[len(bolmo.group(0)):]
  351.                 
  352.             
  353.             self._cur.epilogue = EMPTYSTRING.join(epilogue)
  354.             return None
  355.         
  356.         lines = []
  357.         for line in self._input:
  358.             if line is NeedMoreData:
  359.                 yield NeedMoreData
  360.                 continue
  361.             
  362.             lines.append(line)
  363.         
  364.         self._cur.set_payload(EMPTYSTRING.join(lines))
  365.  
  366.     
  367.     def _parse_headers(self, lines):
  368.         lastheader = ''
  369.         lastvalue = []
  370.         for lineno, line in enumerate(lines):
  371.             if line[0] in ' \t':
  372.                 if not lastheader:
  373.                     defect = errors.FirstHeaderLineIsContinuationDefect(line)
  374.                     self._cur.defects.append(defect)
  375.                     continue
  376.                 
  377.                 lastvalue.append(line)
  378.                 continue
  379.             
  380.             if lastheader:
  381.                 lhdr = EMPTYSTRING.join(lastvalue)[:-1].rstrip('\r\n')
  382.                 self._cur[lastheader] = lhdr
  383.                 lastheader = ''
  384.                 lastvalue = []
  385.             
  386.             if line.startswith('From '):
  387.                 if lineno == 0:
  388.                     mo = NLCRE_eol.search(line)
  389.                     if mo:
  390.                         line = line[:-len(mo.group(0))]
  391.                     
  392.                     self._cur.set_unixfrom(line)
  393.                     continue
  394.                 elif lineno == len(lines) - 1:
  395.                     self._input.unreadline(line)
  396.                     return None
  397.                 else:
  398.                     defect = errors.MisplacedEnvelopeHeaderDefect(line)
  399.                     self._cur.defects.append(defect)
  400.             
  401.             i = line.find(':')
  402.             if i < 0:
  403.                 defect = errors.MalformedHeaderDefect(line)
  404.                 self._cur.defects.append(defect)
  405.                 continue
  406.             
  407.             lastheader = line[:i]
  408.             lastvalue = [
  409.                 line[i + 1:].lstrip()]
  410.         
  411.         if lastheader:
  412.             self._cur[lastheader] = EMPTYSTRING.join(lastvalue).rstrip('\r\n')
  413.         
  414.  
  415.  
  416.